﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;

namespace Pipes.Ui
{
  public partial class Form1 : Form
  {
    private string _compareKey;

    public Form1()
    {
      InitializeComponent();
    }
    
    protected override void OnLoad(EventArgs e)
    {
      var parsers = new List<Parser.IParser>() { new Parser.ArasParser() };
      cboAlgorithm.DataSource = parsers;
    }

    private void btnCompare_Click(object sender, EventArgs e)
    {
      var parser = cboAlgorithm.SelectedItem as Parser.IParser;
      _compareKey = txtKey.Text;

      if (parser != null && !string.IsNullOrEmpty(_compareKey))
      {
        var diffCalc = new Diff.KeyedListDiff();
        var diffs = diffCalc.GetDiff(parser.Parse(txtBase.Text), parser.Parse(txtCompare.Text),
                                     (x) => x.Item(_compareKey),
                                     (x, y) => diffCalc.GetDiff(x, y, (z) => z.Name, Diff.KeyedListDiff.ObjectDiff));
        using (var writer = new System.IO.StringWriter())
        {
          using (var html = Sgml.HtmlTextWriter.Create(writer))
          {
            html.Element("ul");
            foreach (var diff in diffs.Where((d) => d.Action != Diff.DiffAction.None))
            {
              html.Element("li");
              html.Element("p", string.Format("[{0}] {1}", diff.Action, ((Data.IDataRecord)(diff.Base ?? diff.Compare)).Item(_compareKey)));
              if (diff.Action == Diff.DiffAction.Change)
              {
                html.Element("ul");
                foreach (var innerDiff in diff.Changes.Where((d) => d.Action != Diff.DiffAction.None))
                {
                  html.Element("li");
                  if (innerDiff.Action == Diff.DiffAction.Change)
                  {
                    html.Element("p", string.Format("[{0}] {1}, '{2}' -> '{3}'", diff.Action, ((Data.IFieldValue)(innerDiff.Base ?? innerDiff.Compare)).Name,
                                                                                 ((Data.IFieldValue)innerDiff.Base).Value, ((Data.IFieldValue)innerDiff.Compare).Value));
                  }
                  else
                  {
                    html.Element("p", string.Format("[{0}] {1}", diff.Action, ((Data.IFieldValue)(innerDiff.Base ?? innerDiff.Compare)).Name));
                  }
                  html.ElementEnd();
                }
                html.ElementEnd();
              }
              html.ElementEnd();
            }
            html.ElementEnd();
          }
          outputBrowser.DocumentText = writer.ToString();
        }
      }

    }

    private int SortDataRecord(Data.IDataRecord x, Data.IDataRecord y)
    {
      return Compare(x.Item(_compareKey), y.Item(_compareKey), StringComparison.InvariantCultureIgnoreCase);
    }
    private int Compare(object x, object y, StringComparison compare)
    {
      if (x == null && y == null)
      {
        return 0;
      }
      else if (x == null)
      {
        return -1;
      }
      else if (y == null)
      {
        return 1;
      }
      else
      {
        var xString = x as string;
        var yString = y as string;

        if (xString != null && yString != null)
        {
          return string.Compare(xString, yString, compare);
        }
        else
        {
          var xCompare = x as IComparable;
          var yCompare = y as IComparable;
          if (xCompare != null && yCompare != null)
          {
            return xCompare.CompareTo(yCompare);
          }
          else
          {
            return string.Compare(x.ToString(), y.ToString(), compare);
          }
        }
      }
    }
  }
}
